/*****************************************************************************
 * plum_log.h
 *
 * Copyright (C) 2020 Jeasonvor 1101627719@qq.com
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 ****************************************************************************/

/*****************************************************************************
 * Describe ： if you want to use this log file,you must define a physics
 * 			   interface named puts.
 ****************************************************************************/

#ifndef __LOG_H__
#define __LOG_H__

/*****************************************************************************
 * Pre-processor Definitions
 ****************************************************************************/

#define PLUM_LOG_LEVEL_NONE  (1)
#define PLUM_LOG_LEVEL_ERROR (2)
#define PLUM_LOG_LEVEL_WARN  (3)
#define PLUM_LOG_LEVEL_INFO  (4)
#define PLUM_LOG_LEVEL_DEBUG (5)
#define PLUM_LOG_LEVEL_TRACE (6)

#define LOG_MESSAGE_MAXLEN 1024

/*****************************************************************************
 * Public Data
 ****************************************************************************/

/****************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
/*****************************************************************************
 * Public Function Prototypes
 ****************************************************************************/

/**
 * @brief Raw printf log message.
 *
 * @param[in]: module  	- The module name
 * @param[in]: level    - The log level
 * @param[in]: filename - The file name
 * @param[in]: line	   	- The file line
 * @param[in]: fmt	   	- The Pointer to format string, followed by the
 * arguments for conversion.
 */
void _kernel_log_message(const char *module, int level, const char *fmt, ...);

/**
 * @brief Raw printf log message.
 *
 * @param[in]: module	- The module name
 * @param[in]: level    - The log level
 * @param[in]: filename - The location string
 * @param[in]: line	   - The file line
 * @param[in]: prefix   - The pointer to describe
 * @param[in]: ptr	   - The pointer to msg
 * @param[in]: size	   - The number of msg
 */
void _kernel_log_hexdecimal(const char *module, int level, const char *prefix,
                            const void *ptr, int size);

/**
 * @brief:	set log echo direction
 *
 * @param[in]:	print	-	the log direction callback
 *
 * @return:
 */
void _kernel_log_print(int (*print)(const char *fmt, ...));

#define LOG_MESSAGE(module, level, fmt, ...)                         \
    do {                                                             \
        if (LOG_RUN_LEVEL >= level) {                                \
            _log_message(module, level, __FUNCTION__, __LINE__, fmt, \
                         ##__VA_ARGS__);                             \
        }                                                            \
    } while (0)

#define LOG_HEXDECIMAL(module, level, prefix, ptr, len) \
    _log_hexdecimal(module, level, prefix, ptr, len);

#define PRINTK_A(...) LOG_MESSAGE(LOG_LEVEL_ALWAYS, ##__VA_ARGS__)
#define PRINTK_I(...) LOG_MESSAGE(LOG_LEVEL_INFO, ##__VA_ARGS__)
#define PRINTK_W(...) LOG_MESSAGE(LOG_LEVEL_WARN, ##__VA_ARGS__)
#define PRINTK_E(...) LOG_MESSAGE(LOG_LEVEL_ERROR, ##__VA_ARGS__)
#define PRINTK_D(...) LOG_MESSAGE(LOG_LEVEL_DEBUG, ##__VA_ARGS__)

#define LOG_AHEX(prefix, ptr, len) \
    LOG_HEXDECIMAL(LOG_LEVEL_ALWAYS, prefix, (void *)ptr, len)
#define LOG_IHEX(prefix, ptr, len) \
    LOG_HEXDECIMAL(LOG_LEVEL_INFO, prefix, (void *)ptr, len)
#define LOG_WHEX(prefix, ptr, len) \
    LOG_HEXDECIMAL(LOG_LEVEL_WARN, prefix, (void *)ptr, len)
#define LOG_EHEX(prefix, ptr, len) \
    LOG_HEXDECIMAL(LOG_LEVEL_ERROR, prefix, (void *)ptr, len)
#define LOG_DHEX(prefix, ptr, len) \
    LOG_HEXDECIMAL(LOG_LEVEL_DEBUG, prefix, (void *)ptr, len)

/****************************************************************************/
#ifdef __cplusplus
}
#endif

#endif

/****************************************************************************/
/*                                                                          */
/*  End of file.                                                            */
/*                                                                          */
/****************************************************************************/
